import { UUID } from "./common"

export const MANIFEST = chrome.runtime.getManifest()

/** background 打开页面 */
export const openUrl = (url = '') => chrome.tabs.create({url})

/** 兼容 MENIFEST v2 */
export const queryTabs = (queryInfo: chrome.tabs.QueryInfo) => new Promise<chrome.tabs.Tab[]>(resolve => chrome.tabs.query(queryInfo, resolve))
const currentQueryInfo: chrome.tabs.QueryInfo = { active: true, url: [ 'http://*/*', 'https://*/*' ] }

/** 页面 发消息给 background */
export const sendBackgroundMessage = async function <T, F>(msg: T): Promise<F> {
    return chrome.runtime.sendMessage(msg)
}
/** background 或者 popup 发消息给 content */
export const sendContentMessage = async function <T, F>(
    msg: T,
    queryInfo = currentQueryInfo
): Promise<F[]> {
    return queryTabs(queryInfo).then(async (tabs) => {
        const result = []
        for (let i = 0; i < tabs.length; i++) {
            result[i] = await chrome.tabs.sendMessage(tabs[i]?.id, msg)
        }
        return result
    })
}

/** Message事件定义 */
export type OnMessageListener<T, F> = (message: T, sender: chrome.runtime.MessageSender, sendResponse: (response?: F) => void) => void
/** 绑定事件 */
export const addOnMessageListener = <T, F>(listener: OnMessageListener<T,F>) => chrome.runtime.onMessage.addListener(listener)
/** 取消绑定时间 */
export const removeOnMessageListener = <T, F>(listener: OnMessageListener<T,F>) => chrome.runtime.onMessage.removeListener(listener)


export interface ContextMenuProps extends chrome.contextMenus.CreateProperties {
    children?: ContextMenuProps[]
}
/**
 * background 中渲染contextmenu菜单
 * @param createProperties 菜单参数
 * @param mode  "add" 添加模式； "single" 单个模式(默认)
 * @returns menuItemId
 */
export const renderContextMenu = async function renderContextMenu (createProperties: ContextMenuProps, mode: 'add' | 'single' = "single") {
    const { children, ...props } = createProperties
    const parentId = await _renderContextMenu(props, mode)
    if (children?.length > 0) {
        for (let i = 0; i < children.length; i++) {
            const element = children[i];
            await renderContextMenu({...element, parentId}, 'add')
        }
    }
    return parentId
}

const _renderContextMenu = (createProperties: chrome.contextMenus.CreateProperties, mode: 'add' | 'single' = "single") => new Promise<string>(function (resolve) {
    const append = function () {
        const { onclick, ...rest } = createProperties
        rest.id = rest.id || `menuItemId: ${UUID()}`
        chrome.contextMenus.create(rest, function () {
            chrome.contextMenus.onClicked.addListener(function (data, tab) {
                if (data.menuItemId === rest.id) {
                    onclick && onclick(data, tab)
                }
            })
            resolve(rest.id)
        })
    }
    if (mode === 'single') {
        chrome.contextMenus.removeAll(append)
    } else {
        append()
    }
})